#include "stdafx.h"

Hook es_debug;
Hook es_printf;
Hook es_fopen;
Hook es_open;

void debug_pr_h (WORD a, WORD b, char* format, ...);
typedef void (*debug_orig)(WORD,WORD,char*,...);

int printf_h(char* format, ...);
typedef int (*printf_orig)(char*, ...);

FILE* fopen_h(const char* path, const char* mode);
typedef FILE* (*fopen_orig)(const char*, const char*);

int open_h(const char* path, int access, int mode);
typedef int (*open_orig)(const char*,int,int);

debug_orig debug_ptr = NULL;
printf_orig printf_ptr=NULL;
fopen_orig fopen_ptr=NULL;
open_orig open_ptr=NULL;

typedef struct {
	WORD a;
	WORD b;
} debug_filter;

debug_filter df[] = {
	{2,2},
	{0,20},
	{0,21},
	{0,18},
	{40,2},
	{0,5}
};

int seq=0; //sequence counter to manage continuity between logfiles

int write_log(char* file, char * data) {
	char buf[2048];
	sprintf(buf,"SEQ %d: %s",seq,data);
	FILE* fp;
	fp=fopen(file,"a");
	fputs(buf,fp);
	fclose(fp);
	return TRUE;
}

int create_hooks() {
	es_debug.Initialize(0x46A834, debug_pr_h);
	es_debug.Start();
	es_printf.Initialize("_printf", "cw3220.dll", printf_h);
	es_printf.Start();
	es_fopen.Initialize("_fopen", "cw3220.dll", fopen_h);
	es_fopen.Start();
	es_open.Initialize("_open", "cw3220.dll", open_h);
	es_open.Start();
	return TRUE;
}

void debug_pr_h (WORD a, WORD b, char* format, ...){
	char buffer[256];
	char totalBuf[1024];
	int vspRet;
	es_debug.Reset();
	debug_ptr = (debug_orig)es_debug.original_function;

	va_list args;
	va_start (args, format);
	vspRet=vsprintf (buffer,format, args);
	va_end (args);
	
	sprintf(totalBuf,"a: %d, b: %d, msg: <%s>, size %d\n",a,b,buffer);
	bool doPrint=TRUE;
	for(int i=0;i<sizeof(df)/sizeof(debug_filter);i++) {
		if(df[i].a==a && df[i].b==b)
			doPrint=FALSE;
	}
	if(doPrint)
		write_log("c:\\sierra\\es2\\debug.log",totalBuf);

	debug_ptr(a,b,format,args);
	
	es_debug.Place_Hook();

	seq++;
}

int printf_h(char* format, ...) {
	char buffer[1024];
	int ret,vspRet;
	es_printf.Reset();
	printf_ptr = (printf_orig)es_printf.original_function;

	va_list args;
	va_start (args, format);
	vspRet=vsprintf (buffer,format, args);
	va_end (args);
	write_log("c:\\sierra\\es2\\printf.log",buffer);

	ret= printf_ptr(format,args);
	
	es_printf.Place_Hook();

	seq++;

	return ret;
}

FILE* fopen_h(const char* path, const char* mode) {
	FILE* ret;
	char buffer[1024];
	es_fopen.Reset();
	fopen_ptr=(fopen_orig)es_fopen.original_function;
	sprintf(buffer,"call to fopen, path=<%s>, mode=<%s>\n",path,mode);
	write_log("c:\\sierra\\es2\\intercept.log",buffer);
	ret=fopen_ptr(path,mode);
	es_fopen.Place_Hook();
	seq++;
	return ret;
}

int open_h(const char* path, int access, int mode) {
	int ret;
	char buffer[1024];
	es_open.Reset();
	open_ptr=(open_orig)es_open.original_function;
	sprintf(buffer,"call to open, path=<%s>, access=%x, mode=%x\n",path,access,mode);
	write_log("c:\\sierra\\es2\\intercept.log",buffer);
	ret=open_ptr(path,access,mode);
	es_open.Place_Hook();
	seq++;
	return ret;

}